<html>
    <head>
        <title>检测变化的注意事项</title>
    </head>
    <body>
        <script>
            // 二、检测变化的注意事项
                            /*
                                由于JavaScript的限制，Vue "不能检测数组和对象的变化".
                                尽管如此，我们还是有一些办法来回避这些限制，并保证它们的响应性。
                            */

                            // 1、对于对象
                                    /*
                                        Vue 无法检测property的添加或移除。

                                        由于Vue会在初始化实例时对property执行 getter / setter 转化，

                                        所以，property 必须在 data 对象上存在才能让Vue将它转换为响应式的。
                                    */
                                    // 例如：
                                    var vm = new Vue({
                                                data:{
                                                    a:1
                                                }
                                            })

                                            // 'vm.a' 是响应式的
                                             
                                            vm.b=2;
                                            // 'vm.b' 是非响应式的

                                    /*
                                        对于已经创建的实例，Vue"不允许"动态添加 "根级别" 的响应式 property. 

                                        但是， 可以使用 Vue.set(vm.someObject,'b',2)方法向"嵌套对象"添加响应式 property.
                                    */
                                     // 例如：
                                            Vue.set(vm.someObject,'b',2);
                                    
                                    // 您还可以使用 vm.$set 实例方法，这也是全局 Vue.set 方法的别名：
                                            this.$set(this.someObject,'b',2);

                                    /*
                                        有时候你可能需要为已有对象赋值多个新 property,比如使用 Object.assign() 或 _.extend().

                                        但是，这样添加到对象上的新 property 是非响应式的，不会触发更新。

                                        在这种情况下，你应该用原对象与要混合进去的对象的 property 一起创建一个新对象。
                                    */
                                            // Object.assign() 用来做对象的合并，是浅层拷贝，不会做引用的拷贝，而是直接给引用赋值。
                                            // 直接操作this.someObject :  Object.assign(this.someObject,{a:1,b:2})是无效的，不会触发更新
                                            this.someObeject = Object.assign({},this.someObject,{a:1,b:2})


                                // 2、对于数组
                                    /*
                                        Vue不能检测以下数组的变动：
                                             ①、当你利用索引直接设置一个数组项时， 例如： vm.items[indexOfItem] = newValue
                                             ②、当你修改数组的长度时，例如：  vm.items.length = newLength
                                    */
                                    // 举个例子：
                                            var vm = new Vue({
                                                data:{
                                                    items:[
                                                        'a',
                                                        'b',
                                                        'c' 
                                                    ]
                                                }
                                            })

                                    /*
                                        为了解决第一类问题，一下两种方式都可以实现和 vm.items[indexOfItem]= newValue 相同的效果，
                                        同时也将在响应式系统内触发状态更新：
                                    */
                                            //①、 Vue.set
                                            Vue.set(vm.items,indexOfItem,newValue);

                                            

                                           //②、Array.prototype.splice
                                                        /*
                                                                slice() 是JavaScript数组的一个非常强大的内置方法，用于添加或删除数组中的元素。
                                                                它可以直接修改原数组，并并返回被删除的数组元素（如果有）
                                                            */
                                                            array.splice(startIndex,deleteCount,item1,item2,...)
                                                            /*
                                                                start(必须)： 修改的其实位置，如果为负数则从数组末尾考试啊计算。

                                                                deleteCount(可选)： 要删除的元素个数。如果设置为0或者省略，则不删除任何元素

                                                                item1,item2,...(可选)： 要添加到数组中的新元素。可以添加多个元素。
                                                            */
                                            vm.items.splice(indexOfItem, 1, newValue)

                                    // 你也可以使用 vm.$set 实例方法，该方法是全局方法 Vue.set 的一个别名：
                                                    vm.$set(vm.items,indexOfItem,mewValue);
        </script>
    </body>
</html>